/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "imageknife.h"
#include "napi_parser.h"
#include <arkui/native_node_napi.h>
#include <arkui/native_node.h>
#include "imageknifec_test.h"

namespace ImageKnifeTest {

static std::shared_ptr<ImageKnifePro::ImageKnifeNode> g_imageNode = nullptr;
static NativeImage *g_nativeImage = nullptr;
static NativeImage *g_nativeImageAnimator = nullptr;

napi_value CreateNativeNodeWithCAPI(napi_env env, napi_callback_info info)
{
    const size_t argSize = 1;
    size_t argc = argSize;
    napi_value args[argSize] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentSlot;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentSlot);

    //1.创建ImageKnifeOption
    auto imageKnifeOption = std::make_shared<ImageKnifePro::ImageKnifeOption>();

    //2.设置图片加载选项参数，只有主图源loadSrc必填，其它为可选参数
    imageKnifeOption->loadSrc.SetString("https://www.openharmony.cn/assets/logo-eNzoM33i.png");
    imageKnifeOption->fallbackUrls.push_back("https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/"
                                             "22/v3/LKtJB68-RtyrtmC0PQrGZg/p5xqi4a5TGGbpakgFLqVbg.jpg");
    imageKnifeOption->onLoadListener = std::make_shared<ImageKnifePro::OnLoadCallBack>();
    imageKnifeOption->onLoadListener->onLoadStart = [](ImageKnifePro::ImageInfo info) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "IMAGE_KNIFE_PRO", "ImageNode C API OnLoadStart");
    };
    imageKnifeOption->onLoadListener->onLoadFailed = [](std::string err, ImageKnifePro::ImageInfo info) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "IMAGE_KNIFE_PRO",
                     "ImageNode C API OnLoadFailed:%{public}s", err.c_str());
    };
    imageKnifeOption->onLoadListener->onLoadSuccess = [](ImageKnifePro::ImageInfo info) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "IMAGE_KNIFE_PRO", "ImageNode C API OnLoadSuccess");
    };
    imageKnifeOption->onLoadListener->onLoadCancel = [](std::string reason, ImageKnifePro::ImageInfo info) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, "IMAGE_KNIFE_PRO",
                     "ImageNode C API OnLoadCancel:%{public}s", reason.c_str());
    };

    //3. 创建图片组件
    g_imageNode = ImageKnifePro::ImageKnifeNode::CreateImageKnifeNode(imageKnifeOption);
    const int length = 200;
    g_imageNode->SetWidth(length);
    g_imageNode->SetHeight(length);
    //4. 开始加载，如需同步加载，请设置SyncLoad为true
    g_imageNode->Execute();

    OH_ArkUI_NodeContent_AddNode(contentSlot, g_imageNode->GetHandle());
    return nullptr;
}

napi_value DestroyNativeNodeWithCAPI(napi_env env, napi_callback_info info)
{
    if (g_imageNode != nullptr) {
        const size_t argSize = 1;
        size_t argc = argSize;
        napi_value args[argSize] = {nullptr};
        napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    
        // 获取NodeContent
        ArkUI_NodeContentHandle contentSlot;
        OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentSlot);
        OH_ArkUI_NodeContent_RemoveNode(contentSlot, g_imageNode->GetHandle());

        // 组件销毁不再持有指针引用计数
        g_imageNode->DisposeNode();
        g_imageNode = nullptr;
    }
    return nullptr;
}

// 简单验证纯C接口使用情况，查看图片显示是否正确
napi_value CreateNativeImageNodeWithUrl(napi_env env, napi_callback_info info)
{
    // 示例中已创建图片组件
    if (g_nativeImage != nullptr) {
        return nullptr;
    }

    const size_t argSize = 2;
    size_t argc = argSize;
    napi_value args[argSize] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentSlot;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentSlot);
    // 获取图片url
    std::string url = ImageKnifePro::NapiParser::ParseString(env, args[1]);

    // 创建Image组件并上树
    g_nativeImage = CreateNativeImageWithUrl(url.c_str());
    if (g_nativeImage != nullptr) {
        OH_ArkUI_NodeContent_AddNode(contentSlot, g_nativeImage->handle);
    }

    return nullptr;
}

napi_value DestroyNativeImageNode(napi_env env, napi_callback_info info)
{
    const size_t argSize = 1;
    size_t argc = argSize;
    napi_value args[argSize] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentSlot;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentSlot);

    if (g_nativeImage != nullptr) {
        OH_ArkUI_NodeContent_RemoveNode(contentSlot, g_nativeImage->handle);
        ReleaseNativeImage(g_nativeImage);
        g_nativeImage = nullptr;
    }

    return nullptr;
}

// 简单验证纯C接口使用情况，查看图片显示是否正确
napi_value CreateNativeImageAnimatorWithUrl(napi_env env, napi_callback_info info)
{
    // 示例中已创建图片组件
    if (g_nativeImageAnimator != nullptr) {
        return nullptr;
    }

    const size_t argSize = 2;
    size_t argc = argSize;
    napi_value args[argSize] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentSlot;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentSlot);
    // 获取图片url
    std::string url = ImageKnifePro::NapiParser::ParseString(env, args[1]);

    // 创建Image组件并上树
    g_nativeImageAnimator = CreateNativeAnimatorWithUrl(url.c_str());
    if (g_nativeImageAnimator != nullptr) {
        OH_ArkUI_NodeContent_AddNode(contentSlot, g_nativeImageAnimator->handle);
    }

    return nullptr;
}

napi_value DestroyNativeImageAnimatorNode(napi_env env, napi_callback_info info)
{
    const size_t argSize = 1;
    size_t argc = argSize;
    napi_value args[argSize] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取NodeContent
    ArkUI_NodeContentHandle contentSlot;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentSlot);

    if (g_nativeImageAnimator != nullptr) {
        OH_ArkUI_NodeContent_RemoveNode(contentSlot, g_nativeImageAnimator->handle);
        ReleaseNativeImage(g_nativeImageAnimator);
        g_nativeImageAnimator = nullptr;
    }

    return nullptr;
}

napi_value NativeNodeTest(napi_env env, napi_value &exports)
{
    napi_property_descriptor desc[] = {
        {"createNativeNodeWithCAPI", nullptr, CreateNativeNodeWithCAPI,
            nullptr, nullptr, nullptr, napi_default, nullptr},
        {"destroyNativeNodeWithCAPI", nullptr, DestroyNativeNodeWithCAPI,
            nullptr, nullptr, nullptr, napi_default, nullptr},
        {"createNativeImageNodeWithUrl", nullptr, CreateNativeImageNodeWithUrl,
            nullptr, nullptr, nullptr, napi_default, nullptr},
        {"destroyNativeImageNode", nullptr, DestroyNativeImageNode,
            nullptr, nullptr, nullptr, napi_default, nullptr},
        {"createNativeImageAnimatorWithUrl", nullptr, CreateNativeImageAnimatorWithUrl,
            nullptr, nullptr, nullptr, napi_default, nullptr},
        {"destroyNativeImageAnimatorNode", nullptr, DestroyNativeImageAnimatorNode,
            nullptr, nullptr, nullptr, napi_default, nullptr},
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}

}